#pragma once

#include <string>
#include <map>
#include "util/log.hpp"

namespace jvm {
	namespace heap {

		const static std::map<std::string, std::string> g_primitiveTypes =
		{
			{"void", "V"},
			{"boolean", "Z"},
			{"byte", "B"},
			{"short", "S"},
			{"int", "I"},
			{"long", "J"},
			{"char", "C"},
			{"float", "F"},
			{"double", "D"}
		};

		inline std::string toClassName(const std::string& descriptor)
		{
			if (descriptor[0] == '[') return descriptor; // array

			// object
			if (descriptor[0] == 'L') return std::string(descriptor.begin() + 1, descriptor.end());

			for (const auto& [name, desc] : g_primitiveTypes)
			{
				if (desc == descriptor) return name;
			}

			LOG_ERROR("Invalid descriptor: " << descriptor);
			throw std::runtime_error("Invalid descriptor: " + descriptor);
		}

		inline std::string toDescriptor(const std::string& name)
		{
			if (name[0] == '[') return name;
			
			auto it = g_primitiveTypes.find(name);
			if (g_primitiveTypes.end() != it) return it->second;

			return 'L' + name + ';';
		}

		inline std::string getArrayClassName(const std::string& classname)
		{
			return '[' + toDescriptor(classname);
		}

	}// heap
}// namespace jvm